home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / tools / gcc / libnixv1_0.lha / gnu / libnix-sources.lha / sources / misc / detach.c next >
Encoding:
C/C++ Source or Header  |  1995-04-22  |  3.0 KB  |  93 lines

  1. #include <exec/memory.h>
  2. #include <dos/dosextens.h>
  3. #include <dos/dostags.h>
  4. #include <proto/exec.h>
  5. #include <proto/dos.h>
  6. #include <stabs.h>
  7.  
  8. /* Sorry, but the assembler code produced by gcc for this function is too bad.
  9.  * This one is much better!
  10.  */
  11. #ifdef CreateNewProcTags
  12. #undef CreateNewProcTags
  13. static struct Process *createnewproctags(ULONG Tag1,...)
  14. { return CreateNewProc((struct TagItem *)&Tag1); }
  15. #define CreateNewProcTags createnewproctags
  16. #endif
  17.  
  18. extern struct WBStart *_WBenchMsg;
  19. extern char *__commandline;
  20. extern struct DosLibrary *DOSBase;
  21. extern struct ExecBase *SysBase;
  22. extern void *__SaveSP;
  23. extern char __dosname[];
  24.  
  25. extern char *__procname;
  26. extern long __priority;
  27. extern unsigned long __stack;
  28.  
  29. /* I must close a library after my child is running -
  30.  * and closing a library requires a working dispatcher (IMHO).
  31.  * Also semaphores are much smarter ;). Therefore:
  32.  */
  33. static struct SignalSemaphore *sem;
  34.  
  35. void __initdetach(void)
  36.   if(_WBenchMsg!=NULL)
  37.     return;
  38.  
  39.   if(sem!=NULL)           /* I must be the child process */
  40.   { 
  41.     ObtainSemaphore(sem); /* Assert that my parent is already dead */
  42.     ReleaseSemaphore(sem);
  43.     FreeMem(sem,sizeof(struct SignalSemaphore));
  44.     return;
  45.   }
  46.                           /* I must be the parent */
  47.   if((sem=(struct SignalSemaphore *)
  48.          AllocMem(sizeof(struct SignalSemaphore),MEMF_PUBLIC|MEMF_CLEAR))!=NULL)
  49.   { 
  50.     InitSemaphore(sem);
  51.     
  52.     if((DOSBase=(struct DosLibrary *)OpenLibrary(__dosname,37))!=NULL)
  53.     { 
  54.       struct CommandLineInterface *cli;
  55.       void *stack;
  56.  
  57.       cli=Cli();
  58.       
  59.       stack=__SaveSP;
  60.  
  61.       ObtainSemaphore(sem); /* Assert that my child is suspended until I'm finished */
  62.     
  63.         if(CreateNewProcTags(NP_Seglist,cli->cli_Module, /* child process gets my seglist */
  64.                              NP_FreeSeglist,1,           /* and must free it */
  65.                              NP_Cli,1,                   /* it must be a CLI process */
  66.                              NP_StackSize,__stack,       /* it gets a stack */
  67.                              NP_Name,(ULONG)__procname,  /* a name */
  68.                              NP_Priority,__priority,     /* a priority */
  69.                              NP_Arguments,(ULONG)__commandline,/* and my commandline Arguments */
  70.                              TAG_END)!=NULL)
  71.         { cli->cli_Module=0;            /* I'm no longer owner of this */
  72.           CloseLibrary((struct Library *)DOSBase);
  73.           DOSBase=NULL;
  74.  
  75.           /* Adjust stack, release semaphore and return 0 in one.
  76.            * Maybe the 3 movel are a bit too cautious, but they ARE working
  77.            */
  78.           asm("movel %0,sp;movel %1,a6;movel %2,a0;moveql #0,d0;jmp a6@(-570)"::
  79.               "r"(stack),"r"(SysBase),"r"(sem):"sp","a6","a0");
  80.         }
  81.  
  82.       ReleaseSemaphore(sem); /* Again only caution - you never know */
  83.  
  84.       CloseLibrary((struct Library *)DOSBase);
  85.     }
  86.     FreeMem(sem,sizeof(struct SignalSemaphore)); /* Couldn't start child :( */
  87.   }
  88.   exit(20);
  89. }
  90.   
  91. ADD2INIT(__initdetach,-70); /* A very high priority */
  92.